package cn.minimelon.api.service.common;


import cn.hutool.core.util.ObjUtil;
import cn.minimelon.api.constant.Constants;
import cn.minimelon.api.domain.common.LoginUser;
import cn.minimelon.api.domain.enums.UserStatus;
import cn.minimelon.api.domain.system.SysUser;
import cn.minimelon.api.exception.CaptchaException;
import cn.minimelon.api.exception.CaptchaExpireException;
import cn.minimelon.api.exception.ServiceException;
import cn.minimelon.api.exception.UserPasswordNotMatchException;
import cn.minimelon.api.service.system.ISysLoginService;
import cn.minimelon.api.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.Context;
import org.noear.solon.data.cache.CacheService;

import java.util.Date;
import java.util.HashSet;

/**
 * 登录校验方法
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class LoginService {
    @Inject
    TokenService tokenService;

    @Inject
    CacheService cacheService;

    @Inject
    ISysLoginService userLoginService;

    @Inject
    ISysConfigService configService;

    /**
     * 登录验证
     *
     * @param username 用户名
     * @param password 密码
     * @param code     验证码
     * @param uuid     唯一标识
     * @return 结果
     */
    public String login(String username, String password, String code, String uuid) {
        boolean captchaOnOff = configService.selectCaptchaOnOff();
        // 验证码开关
        if (captchaOnOff) {
            validateCaptcha(username, code, uuid);
        }

        LoginUser loginUser = loadUserByUsername(username);
        if (!SecurityUtils.matchesPassword(password, loginUser.getPassword())) {
            throw new UserPasswordNotMatchException();
        }
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

    /**
     * 校验验证码
     *
     * @param username 用户名
     * @param code     验证码
     * @param uuid     唯一标识
     */
    public void validateCaptcha(String username, String code, String uuid) {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        String captcha = cacheService.get(verifyKey, String.class);
        cacheService.remove(verifyKey);
        if (captcha == null) {
            log.error("验证码超时：" + username);
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            log.error("验证码不匹配：" + username);
            throw new CaptchaException();
        }
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(Context.current().realIp());
        sysUser.setLoginDate(new Date());
        userLoginService.updateUserProfile(sysUser);
    }

    public LoginUser loadUserByUsername(String username) {
        SysUser user = userLoginService.selectUserByUserName(username);
        if (ObjUtil.isNull(user)) {
            log.info("登录用户：{} 不存在.", username);
            throw new ServiceException("登录用户：" + username + " 不存在");
        } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            log.info("登录用户：{} 已被删除.", username);
            throw new ServiceException("对不起，您的账号：" + username + " 已被删除");
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户：{} 已被停用.", username);
            throw new ServiceException("对不起，您的账号：" + username + " 已停用");
        }

        return createLoginUser(user);
    }

    public LoginUser createLoginUser(SysUser user) {
        return new LoginUser(user.getUserId(), user.getDeptId(), user, new HashSet<>());
    }
}
